package com.tom.rpc.v2;

import com.tom.RpcRegister;
import com.tom.rpc.v2.common.RpcRequest;
import com.tom.rpc.v2.common.RpcResponse;
import org.springframework.context.ApplicationContext;

import javax.annotation.PostConstruct;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author yanghongjun19
 * @date 2021/01/06
 **/


public class RpcServer {

    private ApplicationContext applicationContext;
    private int port;
    private String host;
    private  RpcRegister rpcRegistry;

    public RpcServer(String hostname,int port, ApplicationContext applicationContext,RpcRegister rpcRegistry ) {
        this.host=hostname;
        this.port = port;
        this.applicationContext = applicationContext;
        this.rpcRegistry=rpcRegistry;
    }

    @PostConstruct
    public void startup() {
        try {
            System.out.println("开始启动");
            ServerSocket serverSocket = new ServerSocket(port);
            System.out.println("host=" + host);
            System.out.println("port=" + port);
            rpcRegistry.createNode(host + ":" + port);
            while (true) {
                Socket socket = serverSocket.accept();
                System.out.println("开始接受数据");
                try (InputStream inputStream = socket.getInputStream();
                     OutputStream outputStream = socket.getOutputStream()) {

                    ObjectInputStream ois = new ObjectInputStream(inputStream);
                    RpcRequest rpcRequest = (RpcRequest) ois.readObject();

                    String beanName = rpcRequest.getClassName();
                    Object bean = applicationContext.getBean(beanName);
                    String methodName = rpcRequest.getMethodName();
                    Object[] parameters = rpcRequest.getParameters();
                    Class<?>[] parameterTypes = rpcRequest.getParameterTypes();

                    Class clazz = bean.getClass();

                    Method method = null;
                    Object result = null;

                    if (parameterTypes == null || parameterTypes.length == 0) {
                        method = clazz.getMethod(methodName);
                        result = method.invoke(bean);
                    } else {
                        method = clazz.getMethod(methodName, parameterTypes);
                        result = method.invoke(bean, parameters);
                    }


                    ObjectOutputStream oos = new ObjectOutputStream(outputStream);
                    RpcResponse rpcResponse = new RpcResponse();
                    rpcResponse.setSuccess(true);
                    rpcResponse.setResult(result);
                    oos.writeObject(rpcResponse);
                    oos.flush();
                }
            }
        } catch (Exception e) {
            System.out.println("启动异常:" + e.getMessage());
        }

    }
}
